package com.my.main.component.interceptor;

import com.my.main.base.entity.Result;
import com.my.main.base.entity.ResultCode;
import com.my.main.base.entity.response.ProfileResult;
import com.my.main.common.utils.JSONUtil;
import com.my.main.entity.userAndRight.SysRightsRoleRouters;
import com.my.main.entity.userAndRight.SysRightsRoleUserRelation;
import com.my.main.service.userAndRight.SysRightsRoleRoutersService;
import com.my.main.service.userAndRight.SysRightsRoleUserRelationService;
import com.my.main.service.userAndRight.SysRightsRoutersApiService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Component
public class ApiPermissionInterceptor implements HandlerInterceptor {

    /** 权限部分参数 */
    public ProfileResult userInfo;

    private List<String> whiteApiList = new ArrayList<>();

    @Autowired
    private SysRightsRoutersApiService sysRightsRoutersApiService;
    @Autowired
    private SysRightsRoleUserRelationService sysRightsRoleUserRelationService;
    @Autowired
    private SysRightsRoleRoutersService sysRightsRoleRoutersService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        Map<String, Object> sqlMap = new HashMap<>();

        // 设置IP
        ContextInfo.set("ip", getIp(request));
        System.out.println(getIp(request));
        // 设置URI
        ContextInfo.set("uri", request.getRequestURI());
        // 设置sessionId
        ContextInfo.set("sessionId", request.getRequestedSessionId());


        /******************** 设置权限拦截功能 mengft 2020-07-18 start ***************************/
        // api路径
        String apiUrl = request.getRequestURI();

        // 如果路径中包含/open/就不拦截
        if (apiUrl.contains("/open/")) {
            return true;
        }

        // 如果请求为白名单则跳过不拦截
        for(String whiteApi: whiteApiList) {
            if (whiteApi.equals(apiUrl)) {
                return true;
            }
        }

        String referer = request.getHeader("Referer");
        if (referer == null) {
            Result result = new Result(ResultCode.FAIL, "路由不能为空");
            out(JSONUtil.serializer(result), response);
            return false;
        }

        long countAll = 0;
        //获取session中的安全数据
        Subject subject = SecurityUtils.getSubject();
        //1.subject获取所有的安全数据集合
        PrincipalCollection principals = subject.getPrincipals();
        if(principals != null && !principals.isEmpty()){
            //2.获取安全数据
            this.userInfo  = (ProfileResult)principals.getPrimaryPrincipal();
        }

        String userId = "";

        userId = userInfo.getUserId();
        sqlMap.clear();
        sqlMap.put("userId", userId);
        sqlMap.put("limit", 0);
        List<SysRightsRoleUserRelation> sysRightsRoleUserRelations = sysRightsRoleUserRelationService.queryListByMap(sqlMap);
        for (SysRightsRoleUserRelation sysRightsRoleUserRelation : sysRightsRoleUserRelations) {
            sqlMap.clear();
            sqlMap.put("roleId", sysRightsRoleUserRelation.getRoleId());
            List<SysRightsRoleRouters> sysRightsRoleRouterList = sysRightsRoleRoutersService.queryList(sqlMap);
            for (SysRightsRoleRouters rightsRoleRouters : sysRightsRoleRouterList) {
                // 正则
//                    String reg = "^https?:\\/\\/[^:|\\/]+:?[0-9]{0,5}";
                // 路由
//                    String routerPath = referer.replaceFirst(reg, "").split("\\?")[0];

                // 查询权限
                sqlMap.clear();
//                    sqlMap.put("path", routerPath);
                sqlMap.put("apiUrl", apiUrl);
                sqlMap.put("routerId", rightsRoleRouters.getRouterId());
                Long count = sysRightsRoutersApiService.queryCount(sqlMap);
                countAll += count;
            }
        }

        if (countAll < 1) {
            Result result = new Result(ResultCode.UNAUTHORISE);
            out(JSONUtil.serializer(result), response);
            return false;
        }

        /******************** 设置权限拦截功能 mengft 2020-07-18 end ***************************/

        return true;
    }

    public String getIp(HttpServletRequest request) {
        String header = request.getHeader("x-forwarded-for");
        String ip = null;
        if (StringUtils.isNotBlank(header) && !"unknown".equalsIgnoreCase(header)) {
            ip = header.split(",")[0];
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    public void setWhiteApiList(List<String> whiteApiList) {
        this.whiteApiList = whiteApiList;
    }

    // 输出
    private void out(String str, HttpServletResponse response) {
        response.setContentType("text/html;charset=utf-8");
        response.setCharacterEncoding("utf-8");

        try {
            PrintWriter out = response.getWriter();

            out.write(str);
            out.flush();
            out.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}
